﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Web;

namespace Yeetop.PayHub.EToPay
{
    /// <summary>
    /// 壹支付 支付网关
    /// Copyright © Yeetop Inc.(www.yeetop.com)  All rights reserved. 
    /// </summary>
    /// <history>
    /// [JianTao] 2010-01-05 Created 
    /// </history>
    public class EToPayPayment : BasePayment
    {
        public EToPayPayment()
            : base()
        { }

        private EToPayTradeInfo Trade;

        public override void PaySend(MerchantInfo merchant, ITradeInfo trade)
        {
            Trade = (EToPayTradeInfo)trade;
            Merchant = merchant;

            StringBuilder builder = new StringBuilder();
            builder.Append(CreateFormField("p01_service", Trade.p01_service));
            builder.Append(CreateFormField("p02_out_ordercode", Trade.p02_out_ordercode));
            builder.Append(CreateFormField("p03_payamount", Trade.p03_payamount));
            builder.Append(CreateFormField("p04_sitecode", Trade.p04_sitecode));
            builder.Append(CreateFormField("p05_subject", Trade.p05_subject));
            builder.Append(CreateFormField("p06_body", Trade.p06_body));
            builder.Append(CreateFormField("p07_price", Trade.p07_price));
            builder.Append(CreateFormField("p08_quantity", Trade.p08_quantity));
            builder.Append(CreateFormField("p09_notify_url", Trade.p09_notify_url));
            builder.Append(CreateFormField("p10_note", Trade.p10_note));
            builder.Append(CreateFormField("sign", SendSign()));

            //HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312");

            SubmitPayForm(CreateForm(builder.ToString(), Merchant.Gateway));
        }

        protected override PayStatus CheckReturnData(CheckBillDelegate checkBill)
        {
            // 通知数据中必须包含的Key，如果没有表示数据可能非法
            string[] checkParma = { "p01_service", "p02_out_ordercode", "p03_payamount", "p04_sitecode", "p05_subject", "p06_body", "p07_price", "p08_quantity", "p10_note", "p11_status", "p12_ordercode", "sign" };

            if (!ReceiveData.NotifyData.ContainsKeys(checkParma))
            {
                return PayStatus.ServerDataIllegal;
            }

            if (ReceiveData.NotifyData["sign"] == NotifySign())
            {
                if (ReceiveData.NotifyData["p11_status"].Equals("success"))
                {
                    BillInfo bill = new BillInfo();
                    bill.MerchantUID = Merchant.UID;
                    bill.OrderId = ReceiveData.NotifyData["p02_out_ordercode"];
                    bill.OrderAmount = ReceiveData.NotifyData["p03_payamount"];
                    bill.PayPlatform = PayPlatformType.EToPay;

                    return checkBill(bill);
                }
                else
                {
                    return PayStatus.Failure;
                }
            }
            else
            {
                return PayStatus.SignError;
            }
        }

        protected override bool CheckNotifyData(CheckUpdateBillDelegate checkUpdateBill)
        {
            // 通知数据中必须包含的Key，如果没有表示数据可能非法
            string[] checkParma = { "p01_service", "p02_out_ordercode", "p03_payamount", "p04_sitecode", "p05_subject", "p06_body", "p07_price", "p08_quantity", "p10_note", "p11_status", "p12_ordercode", "sign" };

            if (!ReceiveData.NotifyData.ContainsKeys(checkParma))
            {
                System.Web.HttpContext.Current.Response.Write("error");

                return false;
            }

            PayStatus payStatus;

            if (ReceiveData.NotifyData["sign"] == NotifySign())
            {
                if (ReceiveData.NotifyData["p11_status"].Equals("success"))
                {
                    BillInfo bill = new BillInfo();
                    bill.MerchantUID = Merchant.UID;
                    bill.OrderId = ReceiveData.NotifyData["p02_out_ordercode"];
                    bill.OrderAmount = ReceiveData.NotifyData["p03_payamount"];
                    bill.PayPlatform = PayPlatformType.EToPay;

                    payStatus = checkUpdateBill(bill);
                }
                else
                {
                    payStatus = PayStatus.Failure;
                }
            }
            else
            {
                payStatus = PayStatus.SignError;
            }

            if (payStatus == PayStatus.Succeed)
            {
                System.Web.HttpContext.Current.Response.Clear();
                System.Web.HttpContext.Current.Response.Write("1000");
                System.Web.HttpContext.Current.Response.End();

                return true;
            }
            else
            {
                System.Web.HttpContext.Current.Response.Clear();
                System.Web.HttpContext.Current.Response.Write("error");
                System.Web.HttpContext.Current.Response.End();

                return false;
            }
        }

        public override PayPlatformType PayPlatform
        {
            get { return PayPlatformType.EToPay; }
        }

        protected override string SendSign()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("p01_service=" + Trade.p01_service);
            builder.Append("&p02_out_ordercode=" + Trade.p02_out_ordercode);
            builder.Append("&p03_payamount=" + Trade.p03_payamount);
            builder.Append("&p04_sitecode=" + Trade.p04_sitecode);
            builder.Append("&p05_subject=" + Trade.p05_subject);
            builder.Append("&p06_body=" + Trade.p06_body);
            builder.Append("&p07_price=" + Trade.p07_price);
            builder.Append("&p08_quantity=" + Trade.p08_quantity);
            builder.Append("&p09_notify_url=" + Trade.p09_notify_url);
            builder.Append("&p10_note=" + Trade.p10_note);
            builder.Append("&merchantcode=" + Merchant.UID);
            builder.Append("&merchantkey=" + Merchant.Key);
            return MD5By32(builder.ToString(), Encoding.GetEncoding("gb2312"));
        }

        protected override string NotifySign()
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("p01_service=" + ReceiveData.NotifyData["p01_service"]);
            builder.Append("&p02_out_ordercode=" + ReceiveData.NotifyData["p02_out_ordercode"]);
            builder.Append("&p03_payamount=" + ReceiveData.NotifyData["p03_payamount"]);
            builder.Append("&p04_sitecode=" + ReceiveData.NotifyData["p04_sitecode"]);
            builder.Append("&p05_subject=" + ReceiveData.NotifyData["p05_subject"]);
            builder.Append("&p06_body=" + ReceiveData.NotifyData["p06_body"]);
            builder.Append("&p07_price=" + ReceiveData.NotifyData["p07_price"]);
            builder.Append("&p08_quantity=" + ReceiveData.NotifyData["p08_quantity"]);
            builder.Append("&p10_note=" + ReceiveData.NotifyData["p10_note"]);
            builder.Append("&p11_status=" + ReceiveData.NotifyData["p11_status"]);
            builder.Append("&p12_ordercode=" + ReceiveData.NotifyData["p12_ordercode"]);
            builder.Append("&merchantcode=" + Merchant.UID);
            builder.Append("&merchantkey=" + Merchant.Key);
            return MD5By32(builder.ToString(), Encoding.GetEncoding("gb2312"));
        }

        /// <summary>
        /// MD5算法加密字符串( 32位 )
        /// </summary>
        /// <param name="text">要加密的字符串</param>    
        /// <param name="encoding">字符编码</param>    
        public static string MD5By32(string text, Encoding encoding)
        {
            try
            {
                //创建MD5密码服务提供程序
                MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

                //计算传入的字节数组的哈希值
                byte[] hashCode = md5.ComputeHash(encoding.GetBytes(text));

                //释放资源
                md5.Clear();

                //返回MD5值的字符串表示
                string temp = "";
                for (int i = 0, len = hashCode.Length; i < len; i++)
                {
                    temp += hashCode[i].ToString("x").PadLeft(2, '0');
                }
                return temp;
            }
            catch
            {
                return string.Empty;
            }
        }
    }
}
